package com.glp.work.flow.listener;

import com.glp.work.flow.constant.MessageTypeEnum;
import com.glp.work.flow.constant.OrderOperation;
import com.glp.work.flow.constant.OrderStatus;
import com.glp.work.flow.pojo.WfOrder;
import com.glp.work.flow.request.ProcessStatusRequest;
import com.glp.work.flow.service.OrderInfoService;
import com.glp.work.flow.service.SyncProcessStatusService;
import com.glp.work.flow.workflow.plugin.flowable.constant.FlowConstant;
import com.glp.work.flow.workflow.plugin.flowable.service.FlowProcessDefinitionService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.flowable.editor.language.json.converter.util.CollectionUtils;
import org.flowable.engine.HistoryService;
import org.flowable.engine.TaskService;
import org.flowable.engine.delegate.DelegateExecution;
import org.flowable.engine.delegate.ExecutionListener;
import org.flowable.engine.task.Comment;
import org.flowable.task.api.history.HistoricTaskInstance;
import org.flowable.variable.api.persistence.entity.VariableInstance;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.mail.Message;
import java.util.List;
import java.util.stream.Collectors;

/** 
* 全局监听器
* @author  pengjia 
* @version 2020年5月27日 下午7:48:12 
*/
@Component
@Slf4j
public class GlobalExecutionHandler implements ExecutionListener {

	private static final long serialVersionUID = -5782298921951616053L;
	
    private static OrderInfoService orderInfoService;
    
    private static SyncProcessStatusService syncProcessStatusService;
    
    private static HistoryService historyService;
    
    private static TaskService taskService;

	private static FlowProcessDefinitionService flowProcessDefinitionService;

    
    public static final String GLOBAL_LISTENER_IMPL ="com.glp.work.flow.listener.GlobalExecutionHandler";
    
	@Override
	public void notify(DelegateExecution execution) {
		log.info("【执行监听器】Event={}", execution.getEventName());
		if(GlobalExecutionHandler.EVENTNAME_START.equals(execution.getEventName())) {
			log.info("GlobalExecutionHandler 暂无处理逻辑");
		}else if(GlobalExecutionHandler.EVENTNAME_TAKE.equals(execution.getEventName())) {
			log.info("GlobalExecutionHandler 暂无处理逻辑");
		}else if(GlobalExecutionHandler.EVENTNAME_END.equals(execution.getEventName())) {
			log.info("流程结束");
			endHandler(execution);
	    }	        
	}
	
	private void endHandler(DelegateExecution execution) {
		String createUser = null;
		Object submitter = execution.getVariables().get(FlowConstant.SUBMITTER);
		if (submitter != null) {
			createUser = submitter.toString();
		}
		ProcessStatusRequest request = new ProcessStatusRequest();
		request.setLogo(FlowConstant.LAST);
		request.setMessageType(MessageTypeEnum.END_EVENT.getType());
		request.setProcessId(execution.getProcessInstanceId());
		request.setCurrentNode("结束");
		HistoricTaskInstance historicTaskInstance = historyService.createHistoricTaskInstanceQuery().processInstanceId(execution.getProcessInstanceId()).orderByTaskCreateTime().desc().list().get(0);
		request.setUserNo(historicTaskInstance.getAssignee());
		request.setPreviousNode(historicTaskInstance.getName());
		String hisTaskId = historicTaskInstance.getId();
		log.info("ProcessId={}，Event End Vars：{}", execution.getProcessInstanceId(), execution.getVariables());
		WfOrder record = orderInfoService.queryWfOrderByPorcessId(execution.getProcessInstanceId());
        request.setProcessDefKey(record.getProcDefKey());
		request.setOrderId(record.getOrderId());
		request.setIndex_1(record.getIndex_1());
		request.setIndex_2(record.getIndex_2());
		request.setIndex_3(record.getIndex_3());
//		request.setTaskDefId(historicTaskInstance.getTaskDefinitionKey());
		request.setProcessDefId(execution.getProcessDefinitionId());
		request.setSubmitUser(createUser);
		if (StringUtils.isNotBlank(execution.getProcessInstanceId())) {
			log.info("历史任务ID={}", hisTaskId);
			if (StringUtils.isNotBlank(hisTaskId)) {
				List<Comment> commentList = taskService.getTaskComments(hisTaskId);
				if (CollectionUtils.isNotEmpty(commentList)) {
					List<String> messageList = commentList.stream().map(Comment::getFullMessage).collect(Collectors.toList());
					request.setComments(messageList);
				}
			}
		}
    	if(execution.getVariables() != null
    			&& execution.getVariables().get(FlowConstant.AUDIT_PASS) != null) {
        	if(OrderOperation.PASS.name().equals(execution.getVariables().get(FlowConstant.AUDIT_PASS))) {
        		record.setOrderStatus(OrderStatus.PASS.getCode());
				record.setCurrentNode("结束");
        		request.setStatus(OrderStatus.PASS);
				request.setOperation((String)execution.getVariables().get(FlowConstant.AUDIT_PASS));

    			log.info("最后一个节点审批通过。更新工单状态为：审批通过。 processId：{}, statut：{}", execution.getProcessInstanceId(), request.getStatus());
        		orderInfoService.updateWfOrder(execution.getProcessInstanceId(), record);
            	if(execution.getVariables().get(FlowConstant.APPID) != null) {
            		syncProcessStatusService.syncProcessStatus((String)execution.getVariables().get(FlowConstant.APPID), request);	
            	}
				VariableInstance variableInstance = execution.getVariableInstance(FlowConstant.IS_SUPER_FLOW_DEF);
				if (variableInstance!=null){
					String cachedValue = (String)variableInstance.getCachedValue();
					flowProcessDefinitionService.modelStatusUpdatedeploy(cachedValue);
				}
	        }else {
				record.setOrderStatus(OrderStatus.FAIL.getCode());
				record.setCurrentNode("结束");
				orderInfoService.updateWfOrder(execution.getProcessInstanceId(), record);
	        	log.info("审批不通过（审批拒绝） processId={}。返回拒绝原因={}", execution.getProcessInstanceId(), request.getComments());
        		request.setStatus(OrderStatus.FAIL);
				request.setOperation((String)execution.getVariables().get(FlowConstant.AUDIT_PASS));
            	if(execution.getVariables().get(FlowConstant.APPID) != null) {
            		syncProcessStatusService.syncProcessStatus((String)execution.getVariables().get(FlowConstant.APPID), request);	
            	}
				VariableInstance variableInstance = execution.getVariableInstance(FlowConstant.IS_SUPER_FLOW_DEF);
				if (variableInstance!=null){
					String cachedValue = (String)variableInstance.getCachedValue();
					flowProcessDefinitionService.noModelStatusUpdatedeploy(cachedValue);
				}
	        }
    	}
	}

    @Autowired
    public void setTaskService(TaskService taskService) {
    	GlobalExecutionHandler.taskService = taskService;
    }

    @Autowired
    public void setHistoryService(HistoryService historyService) {
    	GlobalExecutionHandler.historyService = historyService;
    }
	
	@Autowired
	public void setOrderInfoService(OrderInfoService orderInfoService) {
		GlobalExecutionHandler.orderInfoService = orderInfoService;
	}

	@Autowired
	public void setSyncProcessStatusService(SyncProcessStatusService syncProcessStatusService) {
		GlobalExecutionHandler.syncProcessStatusService = syncProcessStatusService;
	}

	@Autowired
	public void setFlowProcessDefinitionService(FlowProcessDefinitionService flowProcessDefinitionService) {
		GlobalExecutionHandler.flowProcessDefinitionService = flowProcessDefinitionService;
	}
}